package org.jeecg.server;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import org.jeecg.handler.MsgHandler;
import org.jeecg.handler.MyServerHandler;
import org.jeecg.handler.MyServerInitializer;
import org.jeecg.handler.NettyUdpServerHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

/**
 * 服务端基本配置，通过一个静态单例类，保证启动时候只被加载一次
 *
 * @author asus
 */
@Component
public class NettyServer {

    @Value("${work.push.port}")
    private Integer udpPort;
    @Value("${work.push.isopen}")
    private boolean isOpen;
    private ApplicationContext applicationContext;
    @Autowired
    private NettyUdpServerHandler handler;
    @Autowired
    private MyServerHandler msgHandler;

    public NettyServer(ApplicationContext applicationContext) throws InterruptedException {
        this.applicationContext = applicationContext;
    }

    public void run() throws Exception {
        if (isOpen) {
            NioEventLoopGroup boosGroup = null;
            NioEventLoopGroup workGroup = null;
            try {
                System.out.println("开始创建netty TCP服务");
                boosGroup=new NioEventLoopGroup();
                workGroup=new NioEventLoopGroup();
                ServerBootstrap serverBootstrap = new ServerBootstrap();
                serverBootstrap.group(boosGroup,workGroup);
                //系统用于临时存放已完成三次握手的请求的队列的最大长度，如果连接建立频繁，服务器处理创建新连接较慢，可以适当调大这个参数
                serverBootstrap.option(ChannelOption.SO_BACKLOG,1024);
                serverBootstrap.channel(NioServerSocketChannel.class);
                //一定要用这种方式设置handler，否则客户端一旦关闭连接之后就连接不上来
                serverBootstrap.childHandler(new MyServerInitializer(applicationContext));
                Channel serverChannel = serverBootstrap.bind(udpPort).sync().channel();
                System.out.println("netty TCP服务启动成功，端口：" + udpPort);
                serverChannel.closeFuture().sync();
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                if(workGroup!=null){
                    workGroup.shutdownGracefully();
                }
                if(boosGroup!=null){
                    boosGroup.shutdownGracefully();
                }
                System.out.println("程序异常结束");
            }
        }
    }


}